package com.hoapital.outpbillwork.module.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hoapital.outpbillwork.billWorkHandler.AbstractBillWorkBusiness;
import com.hoapital.outpbillwork.billWorkHandler.BillWorkHandler;
import com.hoapital.outpbillwork.billWorkHandler.BillWorkHandlerStrategy;
import com.hoapital.outpbillwork.billWorkHandler.LabBillJob;
import com.hoapital.outpbillwork.function.SelectData;
import com.hoapital.outpbillwork.function.SelectDataThread;
import com.hoapital.outpbillwork.module.controller.vo.SendOrderApplyHl7;
import com.hoapital.outpbillwork.module.controller.vo.SendOrderBillHl7;
import com.hoapital.outpbillwork.module.service.AppConfigerBaseinfoService;
import com.hoapital.outpbillwork.module.service.DrugPrescMasterService;
import com.hospital.api.RemoteBillService;
import com.hospital.common.core.constants.OrderConstant;
import com.hospital.common.core.exception.ExceptionHelp;
import com.hospital.common.core.exception.ExceptionHelpEnum;
import com.hospital.common.core.exception.ExceptionPrint;
import com.hospital.common.core.module.controller.vo.CancelOrder;
import com.hoapital.outpbillwork.module.controller.vo.OrderInfo;
import com.hoapital.outpbillwork.module.entity.AppConfigerBaseinfo;
import com.hospital.common.core.result.ErrorTip;
import com.hospital.common.core.result.SuccessTip;
import com.hospital.common.core.result.Tip;
import com.hospital.common.core.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StopWatch;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author lvyao
 * @description 门诊开单业务控制类
 * @date 2021/12/20
 */
@RestController
@RequestMapping("/orderwork")
@Slf4j
public class OutpOrderWork {
    @Resource
    private AppConfigerBaseinfoService appConfigerBaseinfoService;

    @Autowired
    private SelectData selectData;

    @Autowired
    private SelectDataThread selectDataThread;

    @Resource
    private DrugPrescMasterService drugPrescMasterService;

    @Resource
    private RemoteBillService remoteBillService;

    /**
     * 混合项目门诊开单
     *
     * @param requestVal
     * @param request
     * @return
     */
    @PostMapping(value = "/order", produces = {"application/json;charset=UTF-8"})
    public Tip getRemoteInfo(@RequestBody String requestVal, HttpServletRequest request) {
        String retunStr = null;
        Tip tip = null;
        OrderInfo orderInfo = null;
        try {
            orderInfo = JSON.parseObject(requestVal, OrderInfo.class);
        } catch (Exception e) {
            tip = new ErrorTip("1001", "入参格式转换出错:" + e.getMessage());
            return tip;
        }
        BillWorkHandler billWorkHandler = new LabBillJob();
        BillWorkHandlerStrategy billWorkHandlerStrategy = new BillWorkHandlerStrategy(billWorkHandler);
        try {
            tip = billWorkHandlerStrategy.getResult(orderInfo, request, remoteBillService);
        } catch (ExceptionHelp exceptionHelp) {
            tip = new ErrorTip("123", "错误！");
            tip.setMessage(exceptionHelp.getMessage());
            tip.setCode(exceptionHelp.getCode());
            if (exceptionHelp.getCode() > 0) {
                return tip;
            }
        }
        return tip;
    }

    /**
     * 开单默认数据查询
     *
     * @param appString
     * @param request
     * @return
     */
    @PostMapping(value = "/orderdefaultinfo", produces = {"application/json;charset=UTF-8"})
    public Tip getDefaultOrderInfo(@RequestBody String appString, HttpServletRequest request) {
        Tip tip = null;
        try {
            AppConfigerBaseinfo appConfigerBaseinfo = JSON.parseObject(appString, AppConfigerBaseinfo.class);
            SuccessTip successTip = new SuccessTip();
            if (appConfigerBaseinfo.getAppName() == null || appConfigerBaseinfo.getParameterName() == null) {
                return new ErrorTip("1003", "参数AppName或ParameterName异常，请检查入参");
            }
            List<AppConfigerBaseinfo> appConfigerBaseinfos = appConfigerBaseinfoService.list(new QueryWrapper<AppConfigerBaseinfo>()
                    .apply(" app_name = {0} and parameter_name = {1}", appConfigerBaseinfo.getAppName(),
                            appConfigerBaseinfo.getParameterName()));
            if (appConfigerBaseinfos.isEmpty()) {
                return new ErrorTip("1005", "根据传入参数未获取到配置信息或获取多条配置！");
            }
            String defaultInfo = appConfigerBaseinfos.stream().map(AppConfigerBaseinfo::getParainitValue).collect(Collectors.joining(""));
            successTip.setCode(200);
            successTip.setMessage(defaultInfo);
            tip = successTip;
        } catch (Exception e) {
            return new ErrorTip("1004", e.getMessage());
        }
        return tip;
    }

    /**
     * 开单撤销
     *
     * @param requestVal
     * @param request
     * @return
     */
    @PostMapping(value = "/ordercancel", produces = {"application/json;charset=UTF-8"})
    public Tip getRemoteInfo(@RequestBody @Valid String requestVal, HttpServletRequest request, BindingResult bindingResult) {
        Tip tip;
        log.info("取消订单项目调用入参：" + requestVal);
        CancelOrder receive = null;
        try {
            receive = JSON.parseObject(requestVal, CancelOrder.class);
        } catch (Exception e) {
            tip = new ErrorTip("1001", "入参格式转换出错:" + e.getMessage());
        }
        BillWorkHandler billWorkHandler = new LabBillJob();
        BillWorkHandlerStrategy billWorkHandlerStrategy = new BillWorkHandlerStrategy(billWorkHandler);
        try {
            tip = billWorkHandlerStrategy.getResult(receive, request);
        } catch (ExceptionHelp exceptionHelp) {
            tip = new ErrorTip("123", "错误！");
            tip.setMessage(exceptionHelp.getMessage());
            tip.setCode(exceptionHelp.getCode());
            if (exceptionHelp.getCode() > 0) {
                return tip;
            }
        }
        return tip;
    }

    /**
     * 开单数据查询
     *
     * @param requestVal
     * @param request
     * @return
     */
    @PostMapping(value = "/orderquery", produces = {"application/json;charset=UTF-8"})
    public Tip queryOrderInfo(@RequestBody String requestVal, HttpServletRequest request) throws InterruptedException {
//        Tip orderData = selectData.getOrderData(requestVal);
        Tip orderData = selectDataThread.getOrderData(requestVal);
        if (orderData.getCode() == 200) {
            orderData.setMessage("查询HIS开单业务数据成功!");
        }
        return orderData;
    }

    /**
     * 选取订单合单
     *
     * @param requestVal
     * @param request
     * @return
     */
    @PostMapping(value = "/ordersure", produces = {"application/json;charset=UTF-8"})
    public Tip sureOrder(@RequestBody String requestVal, HttpServletRequest request) {
        Tip orderData = selectData.getOrderSure(requestVal);
        if (orderData.getCode() == 200) {
            orderData.setMessage("合并HIS业务单成功，请尽快支付!");
        }
        return orderData;
    }

    /**
     * 发送医嘱申请HL7消息
     *
     * @param requestVal
     * @param request
     * @return
     */
    @PostMapping(value = "/sendOrderApply", produces = {"application/json;charset=UTF-8"})
    public Tip sendOrderApply(@RequestBody String requestVal, HttpServletRequest request) {
        String startTime = DateUtil.getAllTime();
        StopWatch stopwatch = new StopWatch();
        stopwatch.start();
        Tip tip = new SuccessTip();
        SendOrderApplyHl7 sendOrderApplyHl7 = JSON.parseObject(requestVal, SendOrderApplyHl7.class);
        BillWorkHandler billWorkHandler = BillWorkHandlerStrategy.getSendType(sendOrderApplyHl7.getOrderType());
        try {
            tip = billWorkHandler.sendApplyHl7File(sendOrderApplyHl7, "", sendOrderApplyHl7.getType());
        } catch (ExceptionHelp exceptionHelp) {
            tip = new ErrorTip("123", "错误！");
            tip.setMessage(exceptionHelp.getMessage());
            tip.setCode(exceptionHelp.getCode());
        } catch (Exception e) {
            tip = new ErrorTip("123", "错误！");
            tip.setMessage(e.getMessage());
            tip.setCode(500);
        } finally {
            stopwatch.stop();
            String endTime = DateUtil.getAllTime();
            ExceptionPrint.printCommString(OrderConstant.PRESC_SEND_FUNCTION_NAME, requestVal, String.valueOf(tip.getCode()), tip.getMessage(),
                    startTime, endTime, String.valueOf(stopwatch.getTotalTimeSeconds()));
        }
        return tip;
    }

    /**
     * 发送医嘱计费HL7消息
     * 保存文件时用visitdate||visitno存储文件，所以计费消息发送时就能按照此方法获取当时生成的申请改变状态继续发送
     *
     * @param requestVal
     * @param request
     * @return
     */
    @PostMapping(value = "/sendOrderBill", produces = {"application/json;charset=UTF-8"})
    public Tip sendOrderBill(@RequestBody String requestVal, HttpServletRequest request) {
        String startTime = DateUtil.getAllTime();
        StopWatch stopwatch = new StopWatch();
        stopwatch.start();
        Tip tip;
        SendOrderBillHl7 sendOrderBillHl7 = JSON.parseObject(requestVal, SendOrderBillHl7.class);
        BillWorkHandler billWorkHandler = new AbstractBillWorkBusiness();
        try {
            tip = billWorkHandler.sendBillHl7Msg(sendOrderBillHl7.getHospitalCode(), sendOrderBillHl7.getHospitalName(),
                    sendOrderBillHl7.getOneKey(), sendOrderBillHl7.getOrderType(), sendOrderBillHl7.getType());
        } catch (ExceptionHelp exceptionHelp) {
            tip = new ErrorTip("123", "错误！");
            tip.setMessage(exceptionHelp.getMessage());
            tip.setCode(exceptionHelp.getCode());
        }
        stopwatch.stop();
        String endTime = DateUtil.getAllTime();
        ExceptionPrint.printCommString(OrderConstant.PRESC_SEND_BILL_FUNCTION_NAME, requestVal, String.valueOf(tip.getCode()), tip.getMessage(),
                startTime, endTime, String.valueOf(stopwatch.getTotalTimeSeconds()));
        return tip;
    }

    /**
     * 审方回传
     *
     * @param requestVal
     * @param request
     * @return
     */
    @PostMapping(value = "prescCheckBack", produces = {"text/plain;charset=UTF-8"})
    public Tip prescCheck(String requestVal, HttpServletRequest request) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
        String line = null;
        while ((line = reader.readLine()) != null) {
            requestVal += line + "\n";
        }
        String startTime = DateUtil.getAllTime();
        StopWatch stopwatch = new StopWatch();
        stopwatch.start();
        Tip tip = new SuccessTip();
        String[] split1 = null;
        try {
            String[] msas = requestVal.split("MSA");
            String replace = "\\|";
            String[] split = msas[1].split(replace);
            split1 = split[6].split("\\^");
        } catch (Exception e) {
            tip = new ErrorTip("123", "错误！");
            ExceptionHelpEnum prescCheckJson = ExceptionHelpEnum.PRESC_CHECK_JSON;
            tip.setMessage(prescCheckJson.getMessage() + e.getMessage());
            tip.setCode(prescCheckJson.getCode());
        }
        try {
            tip = drugPrescMasterService.prescCkeck(split1);
        } catch (ExceptionHelp exceptionHelp) {
            tip = new ErrorTip("123", "错误！");
            tip.setMessage(exceptionHelp.getMessage());
            tip.setCode(exceptionHelp.getCode());
        } catch (Exception e) {
            tip = new ErrorTip("123", "错误！");
            tip.setMessage(e.getMessage());
            tip.setCode(500);
        } finally {
            stopwatch.stop();
            String endTime = DateUtil.getAllTime();
            ExceptionPrint.printCommString(OrderConstant.PRESC_CHECK_FUNCTION_NAME, requestVal, String.valueOf(tip.getCode()), tip.getMessage(),
                    startTime, endTime, String.valueOf(stopwatch.getTotalTimeSeconds()));
        }
        return tip;
    }

}
